package util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * 视频工具类，需要安装ffmpeg工具
 *
 * @author wanglei
 * @date 2021/10/29
 */
public class VideoUtil {

    public static void main(String[] args) throws IOException {

//        String[] codec = getCodec("C:\\Users\\wevil\\Downloads\\2.mp4");
//        System.out.println(Arrays.toString(codec));

        codecConvert("C:\\Users\\wevil\\Downloads\\7.恼人的枪纲.mp4", "C:\\Users\\wevil\\Downloads\\7.恼人的枪纲-h64.mp4", "h264");
    }

    /**
     * 获取视频编码,第一个是视频编码，第二个是音频编码
     * java -version写至标准错误，所以需要pb.redirectErrorStream(true);捕获输出
     *
     * @param filePath 视频文件地址
     * @author wanglei
     * @date 2021/10/29
     */
    public static String[] getCodec(String filePath) throws IOException {
        String[] result = new String[2];
        try {
            ProcessBuilder pb = new ProcessBuilder("ffprobe", "-i", filePath, "-show_streams");
            // java -version写至标准错误，所以需要pb.redirectErrorStream(true);捕获输出
            pb.redirectErrorStream(true);
            // 环境变量
//            Map<String, String> map = pb.environment();
            Process ps = pb.start();

            BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream(), Charset.forName("GBK")));
            String line = null;
            int index = 0;
            while ((line = br.readLine()) != null) {
                // 查找编码
                if (line.contains("codec_name=")) {
                    result[index] = line.replace("codec_name=", "");
                    index++;
                }
            }
            br.close();
            return result;
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        return null;
    }

    /**
     * 视频转码
     *
     * @param src  原视频地址
     * @param dest 转换后的视频地址
     * @param codec 要转换的视频编码，目前只测试了"h264"
     * @author wanglei
     * @date 2021/11/1
     */
    public static void codecConvert(String src, String dest, String codec) {
        try {
            Process process = Runtime.getRuntime().exec("ffmpeg -i " + src + " -vcodec " + codec + " " + dest);
            dealStream(process);
            process.waitFor();
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * 处理process输出流和错误流，防止进程阻塞
     * 在process.waitFor();前调用
     */
    private static void dealStream(Process process) {
        if (process == null) {
            return;
        }
        // 处理InputStream的线程
        new Thread(() -> {
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            try {
                while ((line = in.readLine()) != null) {
                    System.out.println("output: " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        // 处理ErrorStream的线程
        new Thread(() -> {
            BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            try {
                while ((line = err.readLine()) != null) {
                    System.out.println("err: " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    err.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}